/**
 * 
 */
package com.shine.icis.dao.imp;

import java.io.BufferedWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;

import com.shine.icis.dao.IExpSubmitDataDAO;
import com.shine.icis.dao.imp.BaseHibernateDAO;

/**
 * @author zsy
 *
 */
public class ExpSubmitDataDAO extends BaseHibernateDAO implements IExpSubmitDataDAO {
	private static DecimalFormat doubleFormat = new DecimalFormat("0.00");
	private ResultSet resultSet;//结果集
	private ResultSetMetaData metaData;//
	
	private String sql;
	private List<Object> params;

	@Override
	public void init(String sql, List<Object> params) {
		this.sql = sql;
		this.params = params;
	}

	@Override
	public long findSQLDataCount() {
		SQLQuery query = getSession().createSQLQuery("select count(1) as data_count from (" + sql + ")");
		query.addScalar("data_count", Hibernate.LONG);
		if (params != null) {
			for (int i = 0; i < params.size(); i++) {
				query.setParameter(i, params.get(i));
			}
		}
		Long count = (Long)query.uniqueResult();
		return count.longValue();
	}
	
	@Override
	public void writeToFile(BufferedWriter fw) throws IOException {
		StringBuffer row = null;
		Object col = null;
		List<Object> data = nextData();
		while(data != null) {
			row = new StringBuffer();
			for (int i = 0; i < data.size(); i++) {
				col = data.get(i);
				if (col instanceof Double) {//格式化Double
					row.append(doubleFormat.format(col));
				} else {
					row.append(col == null ? "" : col);
				}
				if (i + 1 < data.size()) {
					row.append("|");
				}
			}
			fw.write(row.toString());
			fw.write(0x0A);
			
			data = nextData();
		}
	}
	
	
	private List<Object> nextData() {
		try {
			if (resultSet == null) {
				initResultSet(sql, params);
			}
			if (resultSet.next()) {
				List<Object> datas = new ArrayList<Object>();
				for (int i = 1; i <= metaData.getColumnCount(); i++) {
					Object data = null;
					String cName = metaData.getColumnName(i);
					if (cName.toLowerCase().startsWith("s_")) {
						data = resultSet.getString(i);
					} else if (cName.toLowerCase().startsWith("l_")) {
						data = resultSet.getLong(i);
					} else if (cName.toLowerCase().startsWith("d_")) {
						data = resultSet.getDouble(i);
					}
					datas.add(data);
				}
				return datas;
			} else {
				//手动关ResultSet
				resultSet.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	@SuppressWarnings("deprecation")
	private void initResultSet(String sql, List<Object> params) {
		try {
			Connection con = getSession().connection();//Connection Hibernate管理不用手动关闭
			PreparedStatement sta = con.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.size(); i++) {
					sta.setObject(i + 1, params.get(i));
				}
			}
			resultSet = sta.executeQuery();
			resultSet.setFetchSize(10000);//缓冲大小
			metaData = resultSet.getMetaData();
		} catch (SQLException e) {
			e.printStackTrace();
			throw new HibernateException(e);
		}
	}
	
}
